package com.gs.process.admin.utils;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gs.process.admin.context.ProcessContext;
import com.gs.process.admin.mapper.ApprovalDetailsMapper;
import com.gs.process.admin.service.ApprovalService;
import com.gs.process.admin.service.ProcessNodeService;
import com.gs.process.model.Approval;
import com.gs.process.model.ApprovalDetails;
import com.gs.process.model.ProcessNode;
import com.gs.process.model.dto.Constant;
import com.gs.process.model.dto.TableFieldCondition;
import com.shallowUniverse.http.HttpApiService;
import com.shallowUniverse.http.pojo.HttpResult;
import com.shallowUniverse.model.Result;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author: Shuai Guo
 * @description:
 * @date: 2021/9/27
 * @version: 1.0
 */
public class ProcessUtil {

    public static void populateProcessNode(List<Approval> approvals, ProcessNodeService processNodeService, ApprovalService approvalService) {
        //查询所有节点
        List<ProcessNode> processNodes = processNodeService.list();
        //设置节点中文
        approvals.forEach(approval -> {
            //拆分当前节点
            List<Long> nodes = Arrays.stream(approval.getCurrent().split(",")).map(Long::parseLong).collect(Collectors.toList());
            //设置节点名
            approval.setCurrentNode(
                    processNodes.stream()
                            .filter(processNodeDefinition -> nodes.contains(processNodeDefinition.getSid()))
                            .map(ProcessNode::getName)
                            .collect(Collectors.joining(","))
            );
        });
    }

    public static void populateProcessNode(List<ApprovalDetails> approvalDetailsList, ProcessNodeService processNodeService) {
        //查询所有节点
        List<ProcessNode> processNodeDefinitions = processNodeService.list();
        //设置节点中文
        approvalDetailsList.forEach(approvalDetails -> {
            //拆分当前节点
            List<Long> nodes = Arrays.stream(approvalDetails.getProcessNodeId().split(",")).map(Long::parseLong).collect(Collectors.toList());
            //设置节点名
            approvalDetails.setProcessNodeName(
                    processNodeDefinitions.stream()
                            .filter(processNodeDefinition -> nodes.contains(processNodeDefinition.getSid()))
                            .map(ProcessNode::getName)
                            .collect(Collectors.joining(","))
            );
        });
    }

    public static boolean allAllowed(ProcessNodeService processNodeService, ApprovalDetailsMapper approvalDetailsMapper, Approval approval, ProcessNode currentNode) {
        //判断当前顺序节点是否已经全部通过
        //查找当前审批流顺序所有节点
        List<ProcessNode> currentNodeList = processNodeService.list(
                new QueryWrapper<ProcessNode>().lambda()
                        .eq(ProcessNode::getProcessId, approval.getProcessId())
                        .eq(ProcessNode::getSeq, currentNode.getSeq())
        );
        //查找详情
        List<ApprovalDetails> allowDetails = approvalDetailsMapper.selectList(
                new QueryWrapper<ApprovalDetails>().lambda()
                        .eq(ApprovalDetails::getApprovalId, approval.getSid())
                        .eq(ApprovalDetails::getInfo, Constant.AUDIT_ALLOW_SIGN)
        );
        //返回结果
        AtomicBoolean flag = new AtomicBoolean(true);
        //判断详情是否和当前节点全部匹配
        if (!CollectionUtils.isEmpty(allowDetails)) {
            List<Long> processNodeIds = allowDetails.stream().map(ApprovalDetails::getProcessNodeId).map(Long::parseLong).collect(Collectors.toList());
            currentNodeList.forEach(processNodeDefinition -> {
                if (!processNodeIds.contains(processNodeDefinition.getSid())) {
                    flag.set(false);
                }
            });
        } else {
            flag.set(false);
        }
        return flag.get();
    }

    public static String removeNode(String current, Long currentNodeId) {
        List<String> ids = Arrays.stream(current.split(",")).collect(Collectors.toList());
        ids.remove(String.valueOf(currentNodeId));
        return String.join(",", ids);
    }

    public static void populateUser(List<Approval> approvals, ProcessContext processContext) {
        approvals.forEach(item -> item.setSubmitPerson(processContext.getUser(item.getUserId())));
    }

    public static boolean validate(Approval approval, ProcessNode processNode, HttpApiService httpApiService, String ipAddress) {
        //拿到目标表
        String target = approval.getTarget();
        //拿到目标表主键
        String targetId = approval.getPrimaryKey();
        //拿到目标表主键值
        String id = approval.getTargetId();
        //拿到需要查的字段
        String field = processNode.getField();
        //拿到符号
        String sign = processNode.getSign();
        //拿到节点中的值
        Double count = processNode.getCount();
        //判断符号、count和field是否为空
        if (ObjectUtils.isEmpty(field) || ObjectUtils.isEmpty(sign) || count == null || count == 0) {
            return false;
        }
        //封装参数
        TableFieldCondition condition = new TableFieldCondition();
        condition.setColumn(field);
        condition.setId(id);
        condition.setPrimaryKey(targetId);
        condition.setTable(target);
        //查询出数据
        String result = "";
        try {
            HttpResult httpResult = httpApiService.doPost(ipAddress + ":9001/field", null, condition);
            if (httpResult.getCode() == 200) {
                result = JSON.parseObject(httpResult.getBody(), Result.class).getBody().toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //判断是否为空
        if (ObjectUtils.isEmpty(result)) {
            return false;
        }
        //转换
        double value = Double.parseDouble(result);
        //判断符号
        switch (sign) {
            case Constant.GREAT_EQUALS:
                return value >= count;
            case Constant.GREAT:
                return value > count;
            case Constant.LESS_EQUALS:
                return value <= count;
            default:
                return value < count;
        }
    }
}
